/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core; import java.awt.*; import java.awt.event.*; import java.beans.*; import java.lang.reflect.InvocationTargetException; import java.io.PrintWriter; import java.io.PrintStream; import java.io.StringWriter; import javax.swing.*; import org.openide.windows.*; import org.openide.*; import org.openide.util.enum.*; import org.openide.util.NbBundle; import org.netbeans.core.output.OutPane; /** * Notifies exceptions. * * @author Jaroslav Tulach */ final class NotifyException extends JScrollPane implements ActionListener { static final long serialVersionUID =3680397500573480127L; /** the instance */ private static NotifyException INSTANCE = new NotifyException (); /** max text of exception */ private static final int MAXIMUM_TEXT_WIDTH = 40; /** enuration of Throwables to notify */ private QueueEnumeration exceptions; /** current exception */ private Throwable current; /** dialog descriptor */ private DialogDescriptor descriptor; /** dialog that displayes the exceptions */ private java.awt.Dialog dialog; /** button to show next exceptions */ private JButton next; /** details button */ private JButton details; /** details window */ private OutPane output; /** boolean to show/hide details */ private boolean showDetails; /** Constructor. */ private NotifyException () { super (); next = new JButton (org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_NextException")); details = new JButton (); output = new OutPane (); setViewportView (output); descriptor = new DialogDescriptor ("", ""); // NOI18N descriptor.setModal (false); descriptor.setMessageType (DialogDescriptor.ERROR_MESSAGE); descriptor.setOptions (new Object[] { DialogDescriptor.OK_OPTION, next }); descriptor.setAdditionalOptions (new Object[] { details }); descriptor.setClosingOptions (new Object[0]); descriptor.setButtonListener (this); dialog = TopManager.getDefault ().createDialog (descriptor); } /** Adds new exception into the queue. */ public static void notify (final Throwable t) { SwingUtilities.invokeLater (new Runnable () { public void run () { INSTANCE.updateState (t); /** If netbeans.debug.exceptions is set, print the exception to console */ if (System.getProperty ("netbeans.debug.exceptions") != null) { // NOI18N t.printStackTrace (); } PrintStream ps = TopLogging.getLogOutputStream (); if (t instanceof InvocationTargetException) { ps.println ("InvocationTargetException:"); // NOI18N InvocationTargetException detail = (InvocationTargetException)t; detail.getTargetException ().printStackTrace (ps); } else { t.printStackTrace(ps); } } }); } /** updates the state of the dialog. called only in AWT thread. */ private void updateState (Throwable t) { if (exceptions == null) { // the dialog is not shown exceptions = new QueueEnumeration (); current = t; update (); dialog.show (); } else { // add the exception to the queue exceptions.put (t); next.setVisible (true); } } /** Updates the visual state of the dialog. */ private void update () { // JST: this can be improved in future... String lm = current.getLocalizedMessage (); String nm = current.getMessage (); boolean isLocalized = lm != null && !lm.equals (nm); next.setVisible (exceptions.hasMoreElements ()); details.setText ( showDetails ? org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Exception_Hide_Details") : org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Exception_Show_Details") ); if (current instanceof InvocationTargetException) { // go in current = ((InvocationTargetException)current).getTargetException (); } // setText (current.getLocalizedMessage ()); String title = org.openide.util.NbBundle.getBundle(NotifyException.class).getString("CTL_Title_Exception"); if (showDetails) { descriptor.setMessage (createDetails ()); } else { if (isLocalized) { String msg = current.getLocalizedMessage (); if (msg == null || "".equals(msg)) { // NOI18N msg = org.openide.util.Utilities.wrapString ( msg, MAXIMUM_TEXT_WIDTH, false, false ); } descriptor.setMessage (msg); } else { // emphasize user-non-friendly exceptions // if (this.getMessage() == null || "".equals(this.getMessage())) { // NOI18N descriptor.setMessage ( java.text.MessageFormat.format( NbBundle.getBundle (NotifyDescriptor.class).getString("NTF_ExceptionalException"), new Object[] { current.getClass().getName() } ) ); title = NbBundle.getBundle (NotifyDescriptor.class).getString( "NTF_ExceptionalExceptionTitle" // NOI18N ); } } descriptor.setTitle (title); } /** Create details. */ private JComponent createDetails () { try { output.getOut ().reset (); current.printStackTrace (output.getOut ()); output.setSelectedIndex (0); output.requestFocus (); } catch (java.io.IOException ex) { } return this; } // // Handlers // public void actionPerformed(final java.awt.event.ActionEvent ev) { if (ev.getSource () == next) { current = (Throwable)exceptions.nextElement (); update (); return; } if (ev.getSource () == details) { showDetails = !showDetails; update (); return; } if (ev.getSource () == DialogDescriptor.OK_OPTION) { exceptions = null; dialog.setVisible (false); return; } } // // Listeners // /** * Shows or hides this component depending on the value of parameter. * @param show if true, shows this component; otherwise, hides it. * public void setVisible(boolean visible) { if (visible == true) { // print details to log file if (descriptor != null) { PrintStream ps = TopLogging.getLogOutputStream (); Object detail = descriptor.getDetail(); if (detail instanceof Throwable) { if (detail instanceof InvocationTargetException) { ps.println ("InvocationTargetException:"); ((InvocationTargetException)detail).getTargetException ().printStackTrace (ps); } else { ((Throwable)detail).printStackTrace(ps); } } else { ps.println(detail); } } } super.setVisible(visible); } */ } /* * Log * 6 Gandalf 1.5 1/15/00 Jaroslav Tulach Next is visible when * more exceptions arrives after displaying the first * 5 Gandalf 1.4 1/13/00 Jaroslav Tulach I18N * 4 Gandalf 1.3 1/9/00 Jaroslav Tulach #5148 * 3 Gandalf 1.2 1/9/00 Jaroslav Tulach getLocalizedMessage can * also return null. * 2 Gandalf 1.1 1/5/00 Jaroslav Tulach Next is not visible when * no next exception is there. * 1 Gandalf 1.0 12/30/99 Jaroslav Tulach * $ */